package bootstrap

import (
	"context"
	"game-server/app/middleware"
	"game-server/global"
	"game-server/routes"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/gin-gonic/gin"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
)

func setupRouter() *gin.Engine {
	if global.App.Config.App.Env == "production" {
		gin.SetMode(gin.ReleaseMode)
	}
	router := gin.Default()
	router.Use(gin.Logger(), middleware.CustomRecovery())

	router.Use(middleware.Cors()) // 跨域中间件

	// 前端项目静态资源
	router.StaticFile("/", "./static/dist/index.html")
	router.Static("/assets", "./static/dist/assets")
	router.StaticFile("/favicon.ico", "./static/dist/favicon.ico")
	// 其他静态资源
	router.Static("/public", "./static")
	router.Static("/storage", "./storage/app/public")

	// 添加全局路由前缀
	prefix := "/" + global.App.Config.App.AppName
	apiGroup := router.Group(prefix)

	// Create a new router group for Swagger
	swaggerGroup := apiGroup.Group("/swagger")
	{
		swaggerGroup.GET("/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
	}

	// 注册路由
	routes.SetTagGroupRoutes(apiGroup)      //tag路由
	routes.SetApiGroupRoutes(apiGroup)      //api路由
	routes.SetCategoryGroupRoutes(apiGroup) //
	routes.SetGameGroupRoutes(apiGroup)     //game路由
	routes.SetSysUserRoutes(apiGroup)       //sys_user路由
	routes.SetSysMenuRoutes(apiGroup)       //menu路由
	routes.SetSysRoleRoutes(apiGroup)       //role路由
	routes.SetVpnGroupRoutes(apiGroup)      //vpn路由
	routes.SetArticleGroupRoutes(apiGroup)  //article路由

	// routes.SetSysAssignRoutes(apiGroup) //分配角色和权限

	return router
}

// RunServer 启动服务器
func RunServer() {
	r := setupRouter()

	srv := &http.Server{
		Addr:    ":" + global.App.Config.App.Port,
		Handler: r,
	}

	go func() {
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen: %s\n", err)
		}
	}()

	// 等待中断信号以优雅地关闭服务器（设置 5 秒的超时时间）
	quit := make(chan os.Signal)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	log.Println("Shutdown Server ...")

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := srv.Shutdown(ctx); err != nil {
		log.Fatal("Server Shutdown:", err)
	}
	log.Println("Server exiting")
}
